/*
 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package com.sun.source.util;

import com.sun.source.tree.*;

/**
 * A TreeVisitor that visits all the child tree nodes, and provides
 * support for maintaining a path for the parent nodes.
 * To visit nodes of a particular type, just override the
 * corresponding visitorXYZ method.
 * Inside your method, call super.visitXYZ to visit descendant
 * nodes.
 *
 * @author Jonathan Gibbons
 * @since 1.6
 */
@jdk.Exported
public class TreePathScanner<R, P> extends TreeScanner<R, P> {

  /**
   * Scan a tree from a position identified by a TreePath.
   */
  public R scan(TreePath path, P p) {
    this.path = path;
    try {
      return path.getLeaf().accept(this, p);
    } finally {
      this.path = null;
    }
  }

  /**
   * Scan a single node.
   * The current path is updated for the duration of the scan.
   */
  @Override
  public R scan(Tree tree, P p) {
    if (tree == null) {
      return null;
    }

    TreePath prev = path;
    path = new TreePath(path, tree);
    try {
      return tree.accept(this, p);
    } finally {
      path = prev;
    }
  }

  /**
   * Get the current path for the node, as built up by the currently
   * active set of scan calls.
   */
  public TreePath getCurrentPath() {
    return path;
  }

  private TreePath path;
}
